%%% ------------------------------------------------------------------
%%% Licensed under the Apache License, Version 2.0 (the 'License');
%%%  you may not use this file except in compliance with the License.
%%%  You may obtain a copy of the License at
%%%
%%%      http://www.apache.org/licenses/LICENSE-2.0
%%%
%%% Copyright (c) 2017 dwg <bypf2009@vip.qq.com>
%%%
%%%  Unless required by applicable law or agreed to in writing, software
%%%  distributed under the License is distributed on an 'AS IS' BASIS,
%%%  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%%%  See the License for the specific language governing permissions and
%%%  limitations under the License.
%%%
%%% @doc
%%% @author  dwg <'bypf2009@vip.qq.com'>
%%% @copyright 2017 dwg <bypf2009@vip.qq.com>
%%% @end
%%% created|changed : 2017-09-15 15:21
%%% coding : utf-8
%%% ------------------------------------------------------------------
-module(elcache_dynamic).
-author("dwg").

-export([pool_init/1]).

pool_init(#{} = Pools) ->
    FunStr = make_functions(Pools),
    Router = make_router(Pools),
    ElcacheRouter = elcache_dynamic_module(Router, FunStr),
    {Mod,Code} = dynamic_compile:from_string(ElcacheRouter),
    code:load_binary(Mod, "elcache_router.erl", Code),
    ok;
pool_init(_) ->
    error.

%%
%% pids match list
%%
make_functions(Pools) ->
    Fun = fun(PoolId, #{pids := Pids}, FunList) ->
        make_functions_list(PoolId, 1, Pids, FunList)
    end,
    FunList = maps:fold(Fun, [], Pools),
    prop_funs(FunList).

make_functions_list(PoolId, C, [Pid | TPid], FunList) ->
    Fun =["get_elcache(", PoolId, "," , C, ") ->
    erlang:list_to_pid(\"", erlang:pid_to_list(Pid), "\");\n\n"],
    make_functions_list(PoolId, C + 1, TPid, Fun ++ FunList);
make_functions_list(_, _, [], FunList) ->
    FunList.

prop_funs(FunList) ->
    FunList1 = FunList ++ ["get_elcache(_, _) ->\n    undefined.\n\n"],
    lists:concat(FunList1).
%%
%% router
%%
make_router(Pools) ->
    Fun = fun(PoolId, #{count := Count}, RouteList) ->
        Route = [
"get_elcache(", PoolId, ") ->
    N = erlang:phash2(os:system_time(), ", Count, "),
    get_elcache(", PoolId, ", N + 1);\n\n"],
        Route ++ RouteList
    end,
    RouteList1 = maps:fold(Fun, [], Pools),
    RouteList2 = RouteList1 ++ [
"get_elcache(_) ->
    undefined.\n\n"],
    lists:concat(RouteList2).

%%@private:
elcache_dynamic_module(Router, FunStr) ->
    lists:concat(["
%%% ------------------------------------------------------------------
%%% @doc Router module,by which send Data to cahce process
%%% @author  dwg <'bypf2009@vip.qq.com'>
%%% @copyright 2017 dwg <bypf2009@vip.qq.com>
%%% @end
%%% created|changed : 2017-09-15 15:21
%%% coding : utf-8
%%% ------------------------------------------------------------------
-module(elcache_router).\n
-author(\"dwg\").\n

-export([get_elcache/1]).\n

%%@doc get the pid of cahce process.
-spec get_elcache(PoolId) -> Pid when
    PoolId :: atom(),
    Pid :: pid().\n", Router, FunStr]).
